﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security;
using System.Collections.Concurrent;
using System.Collections;
using System.Drawing;
using System.Dynamic;

using System.Threading;
using System.Net;
using Newtonsoft.Json;
using System.Diagnostics;
using System.Windows.Forms;
using System.Windows.Media.Imaging; //
using App2Wpf.Models;
using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using System.ComponentModel;
using System.Windows.Threading;
//using WriteableBitmapExtenision;
/*
WriteableBitmapExtensions.BlendMode提供了不同的混合模式，用于在WriteableBitmap上进行像素级别的图像混合操作。下面是每种模式的含义：
1.Normal（正常模式）：将上层像素直接覆盖在底层像素上，不进行任何混合操作。
2.Additive（加法模式）：将上层像素的颜色值与底层像素的颜色值相加，并将结果作为混合后的颜色。
3.Subtractive（减法模式）：将上层像素的颜色值减去底层像素的颜色值，并将结果作为混合后的颜色。如果结果小于0，则取0。
4.Multiply（乘法模式）：将上层像素的颜色值与底层像素的颜色值相乘，并将结果作为混合后的颜色。
5.Screen（屏幕模式）：将上层像素的颜色值与底层像素的颜色值的补值相乘，并将结果作为混合后的颜色的补值。即，将上层像素的颜色值和底层像素的颜色值进行反色处理，然后再进行乘法混合。
6.Darken（变暗模式）：将上层像素的颜色值与底层像素的颜色值进行比较，选择较暗的颜色作为混合后的颜色。
7.Lighten（变亮模式）：将上层像素的颜色值与底层像素的颜色值进行比较，选择较亮的颜色作为混合后的颜色。
8.Overlay（叠加模式）：根据底层像素的颜色值来决定混合方式，如果底层像素较亮，则使用Multiply模式混合；如果底层像素较暗，则使用Screen模式混合。
这些混合模式可以帮助开发者实现各种图像处理效果，例如颜色叠加、图像阴影、透明效果等。在使用WriteableBitmapExtensions.BlendMode时，根据需要选择合适的混合模式，对WriteableBitmap进行相应的操作即可。

C# WPF中的WriteableBitmapExtensions.BlendMode枚举定义了不同的混合模式，用于控制像素之间的混合效果。以下是各个模式的含义：

1. Alpha（Alpha = 0）：使用源像素的Alpha通道值来混合颜色。较低的Alpha值会增加透明度。

2. Additive（Additive = 1）：将源像素的颜色值与目标像素的颜色值相加。这会产生更亮的颜色效果，适合于创建光亮或发光的效果。

3. Subtractive（Subtractive = 2）：将源像素的颜色值从目标像素的颜色值中减去。这会产生较暗的颜色效果，适合于创建阴影或深色效果。

4. Mask（Mask = 3）：根据源像素的Alpha通道值来决定是否显示源像素的颜色。当Alpha通道值为0时，目标像素的颜色将被保留；当Alpha通道值为255时，源像素的颜色将完全显示。

5. Multiply（Multiply = 4）：将源像素的颜色值与目标像素的颜色值相乘。这会产生更暗的颜色效果，适合于创建阴影或混合两种颜色的效果。

6. ColorKeying（ColorKeying = 5）：根据源像素的特定颜色值来决定是否显示源像素的颜色。只有当源像素的颜色与指定的颜色值匹配时，才会显示源像素的颜色。

7. None（None = 6）：不进行任何混合操作，直接将源像素复制到目标像素。

使用这些混合模式，可以根据具体的需求实现各种不同的图像处理效果。
*/

namespace App2Wpf
{
    public class ViewerPlus : ObservableObject
    {
        public delegate void refreshRenderHandle(WriteableBitmap block, System.Windows.Int32Rect tempRect, byte[] buffer);

        public event refreshRenderHandle onRendering;

        public delegate void refreshRenderHandle2(byte[] tempBuffer, WriteableBitmap block, System.Windows.Int32Rect tempRect);

        public event refreshRenderHandle2 onRendering2;

        public delegate void ConnectHandle();
        public event ConnectHandle OnConnect;


        public Point destPoint = new Point(0, 0);
        public WriteableBitmap _block;
        public WriteableBitmap block
        {
            get => _block;
            set
            {
                SetProperty(ref _block, value);
            }
        }

        public string ServerAddress { get; set; } = "127.0.0.1";
        public IPAddress Server { get; set; }

        public nameip wininfo { get; set; }

        public int ServerPort { get; set; } = 8021;

        public bool UseTLS1_3 { get; set; }

        public bool DisableVerbosity { get; set; }

        public SecureString SecurePassword { get; set; }

        public String Password { get; set; }

        public ClipboardMode Clipboard { get; set; } = ClipboardMode.Both;

        public int ImageCompressionQuality { get; set; } = 75;

        public bool Resize { get; set; }

        public int ResizeRatio { get; set; } = 90;

        public bool AlwaysOnTop { get; set; }

        public PacketSize packetSize { get; set; } = PacketSize.Size9216;

        public BlockSize blockSize { get; set; } = BlockSize.Size64;

        public bool LogonUI { get; set; }

        public List<PSCustomObject> runspaces { get; set; }

        public clientViewerSession session { get; set; }

        public CardModel _VirtualDeskForm;
        public CardModel VirtualDeskForm
        {
            get => _VirtualDeskForm;
            set
            {
                SetProperty(ref _VirtualDeskForm, value);
            }
        }

        public Bitmap frame;
        public Hashtable virtualDesktopSyncHash { get; set; }
        
        public ConcurrentDictionary<string, ClientIO> virtualDesktopSyncDic { get; set; } = new ConcurrentDictionary<string, ClientIO>();

        public ClientIO outputEventIO { get; set; }

        public Hashtable outputEventSyncHash { get; set; }
        public ConcurrentDictionary<string, ClientIO> outputEventSyncDic { get; set; } = new ConcurrentDictionary<string, ClientIO>();

        public Hashtable HostSyncHash { get; set; } = new Hashtable();

        public ViewerPlus(IPAddress Server, nameip wininfo)
        {
            this.Server = Server;
            this.wininfo = wininfo;
            //init(Server);

            string host = "";
            string ClipboardText = "";
            HostSyncHash.Add("host", host);
            HostSyncHash.Add("ClipboardText", ClipboardText);

            HostSyncHash = Hashtable.Synchronized(HostSyncHash);
        }

        public void init(IPAddress server)
        {

            //Session successfully established, start streaming...

            //Create WinForms Environment...
            VirtualDeskForm = new CardModel();
            

            //(VirtualDeskForm.pictureBox1 as Control).MouseDown += logic_MouseDown;
            //(VirtualDeskForm.pictureBox1 as Control).MouseUp += logic_MouseUp;
            //(VirtualDeskForm.pictureBox1 as Control).MouseMove += logic_MouseMove;
            //(VirtualDeskForm.pictureBox1 as Control).MouseWheel += logic_MouseWheel;

            //(VirtualDeskForm.pictureBox1 as Control).DoubleClick += logic_DoubleClick;
            //(VirtualDeskForm.pictureBox1 as Control).KeyPress += logic_KeyPress;
            //(VirtualDeskForm.pictureBox1 as Control).KeyUp += logic_KeyUp;
            //(VirtualDeskForm.pictureBox1 as Control).KeyDown += logic_KeyDown;
            //(VirtualDeskForm.pictureBox1 as Control).Leave += logic_Leave;

            //this.virtualDesktopDic = new Dictionary<int, remoteWindow>();
            //virtualDesktopDic.Add(0, VirtualDeskForm);

            var tempHashtable = new Hashtable();
            tempHashtable.Add("VirtualDesktop", VirtualDeskForm);
            var virtualDesktopSyncHash = Hashtable.Synchronized(tempHashtable);

            VirtualDeskForm.cardTitle = string.Format(
                "{0} {1}[{2}x{3}]:{4}/{5}-{6}",
                wininfo.name,
                wininfo.ip,
                0,
                0,
                //session.ServerInformation.Version,
                0,
                0,
                0);
            //加载窗口后刷新 20230520
            //Session successfully established, start streaming...
            this.session = new clientViewerSession();
            this.session.Server = server;
            //Task.Run(() =>
            //{
                session.OpenSession();
                session.ConnectDesktopWorker();
                session.ConnectEventsWorker();
                OnConnect();
                var outputEvent = new Hashtable();
                outputEvent.Add("Writer", session.ClientEvents.Writer);
                outputEventSyncHash = Hashtable.Synchronized(outputEvent);
                outputEventSyncDic.GetOrAdd("outputEvent", session.ClientEvents);

                VirtualDeskForm.cardTitle = string.Format(
                    "{0} {1}[{2}x{3}]:{4}/{5}-{6}",
                    wininfo.name,
                    wininfo.ip,
                    session.ViewerConfiguration.RemoteDesktopWidth,
                    session.ViewerConfiguration.RemoteDesktopHeight,
                    //session.ServerInformation.Version,
                    session.ServerInformation.Username,
                    session.ServerInformation.MachineName,
                    session.ServerInformation.WindowsVersion);

                //test 20221107
                //VirtualDeskForm.ClientSize = new Size(
                //    session.ViewerConfiguration.VirtualDesktopWidth,
                //    session.ViewerConfiguration.VirtualDesktopHeight);

                //  Create a thread-safe hashtable to send events to remote server.

                //Hashtable outputable = new Hashtable();
                //outputable.Add("Writer", session.ClientEvents.Writer);
                //var outputEventSyncHash = Hashtable.Synchronized(outputable);

                if (!session.ServerInformation.ViewOnly)
                {

                }

                VirtualDesktopUpdater(session.ClientDesktop,
                virtualDesktopSyncHash,
                session.ViewerConfiguration,
                session.PacketSize);

            //});
            //picturebox 跨线程
            //IngressEventUpdater(session.ClientEvents, virtualDesktopSyncHash, Clipboard);

            //samll window  not control
            //EgressEventUpdater(virtualDesktopSyncHash, Clipboard);
        }


        public void VirtualDesktopUpdater(ClientIO Client,
                Hashtable virtualDesktopSyncHash,
                clientViewerConfiguration ViewerConfiguration,
                PacketSize packetSize)
        {
            byte[] mstruct = new byte[sizeof(Int32) * 3];
            System.IO.MemoryStream mstream = new System.IO.MemoryStream();
            System.Windows.Int32Rect RenderingRect = new System.Windows.Int32Rect(0,0,0,0);
            
            // //bitmap direct operation
            //Bitmap scene = new Bitmap(ViewerConfiguration.RemoteDesktopWidth, ViewerConfiguration.RemoteDesktopHeight);
            //Graphics sceneGraphics = Graphics.FromImage(scene);
            //sceneGraphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;

            //while (!virtualDesktopDic[0].Form.Visible)
            //{
            //    Thread.Sleep(100);

            //}

            //Tiny hack to correctly bring to front window, this is the most effective technique so far.
            //VirtualDesktopSyncHash.VirtualDesktop.Form.TopMost = true;
            //VirtualDesktopSyncHash.VirtualDesktop.Form.TopMost = false;


            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        Client.SSLStream.Read(mstruct, 0, mstruct.Length);

                        long totalBufferSize = System.Runtime.InteropServices.Marshal.ReadInt32(mstruct, 0x0);

                        destPoint.X = System.Runtime.InteropServices.Marshal.ReadInt32(mstruct, 0x4);
                        destPoint.Y = System.Runtime.InteropServices.Marshal.ReadInt32(mstruct, 0x8);

                        mstream.SetLength(totalBufferSize);

                        mstream.Position = 0;

                        while (mstream.Position != mstream.Length)
                        {
                            long bufferSize = mstream.Length - mstream.Position;
                            if (bufferSize > (long)packetSize)
                            {
                                bufferSize = (long)packetSize;
                                int mbufferSize = (int)packetSize;

                            }
                            //读数据数据流到内存中
                            mstream.Write(  Client.BinaryReader.ReadBytes((int)bufferSize),
                                0, 
                                (int)bufferSize );
                        }
                        if (mstream.Length == 0)
                        {
                            continue;
                        }

                        ///# Next Iterations
                        //sceneGraphics.DrawImage(
                        //        System.Drawing.Image.FromStream(mstream),
                        //        destPoint
                        //    );

                        //mstream.Seek(0, System.IO.SeekOrigin.Begin); //指向开始图像头
                        //VirtualDeskForm.cardFrame = clientFunc.msToBitmapImage(mstream);
                        frame =  new Bitmap(mstream);
                        int iW = frame.Width;
                        int iH = frame.Height;
                        if (destPoint.Y + frame.Height > ViewerConfiguration.RemoteDesktopHeight)
                        {
                            iH = frame.Height - (destPoint.Y + frame.Height - ViewerConfiguration.RemoteDesktopHeight);
                        }
                        if (destPoint.X + frame.Width > ViewerConfiguration.RemoteDesktopWidth)
                        {
                            iW = frame.Width - (destPoint.X + frame.Width - ViewerConfiguration.RemoteDesktopWidth);
                        }
                        frame = frame.Clone(new Rectangle(0, 0, iW, iH), System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                        // // for extension blit
                        // 创建WriteableBitmap对象
                        block = new WriteableBitmap(clientFunc.BitmapToBitmapImage(frame));
                        byte[] blockBuffer = clientFunc.BitmapToBytes(frame);

                        RenderingRect = new System.Windows.Int32Rect(destPoint.X, destPoint.Y, iW, iH);

                        //sourceBitmap.Lock(); //线程内对象才能锁住
                        //WriteableBitmapExtensions.Blit(sourceBitmap,
                        //    new System.Windows.Point(RenderingRect.X, RenderingRect.Y),    // 大图或者小图的目的坐标点
                        //    block,                                                  // 输入 writeablebitmap    
                        //    new System.Windows.Rect(0, 0, block.Width, block.Height), //// 输入 writeablebitmap 的 RECT，实际内部只取用高度和宽度
                        //    Colors.White,
                        //    WriteableBitmapExtensions.BlendMode.None);
                        //sourceBitmap.AddDirtyRect(RenderingRect); //在图像未锁定时无法调用此方法
                        //byte[] sourceBuffer = WriteableBitmapExtensions.ToByteArray(sourceBitmap);
                        //sourceBitmap.Unlock();
                        onRendering(block, RenderingRect, blockBuffer);
                        //onRendering2(buffer,block, RenderingRect);
                        
                        //            // 计算图像的字节数
                        //            int bytesPerPixel = (block.Format.BitsPerPixel + 7) / 8;
                        //            int stride = block.PixelWidth * bytesPerPixel;
                        //            // 分配缓冲区
                        //            System.Windows.Int32Rect rect = new System.Windows.Int32Rect(destPoint.X, destPoint.Y, block.PixelWidth, block.PixelHeight);
                        //            byte[] pixelBuffer = new byte[rect.Width * rect.Height * bytesPerPixel];
                        // 复制局部图像的像素数据
                        //block.CopyPixels(rect, pixelBuffer, stride, 0);

                        // 锁定WriteableBitmap的像素缓冲区
                        //Application.Current.Dispatcher.Dispatcher.Invoke(new Action(() =>
                        //{
                        //writeableBitmap.Lock();
                        // 将处理后的像素数据复制回WriteableBitmap
                        //writeableBitmap.WritePixels(rect, pixelBuffer, stride, 0);
                        //writeableBitmap.AddDirtyRect(rect); //更改位图区域
                        // 解锁WriteableBitmap的像素缓冲区
                        // writeableBitmap.Unlock();
                        //}));

                        // 将Bitmap数据复制到WriteableBitmap
                        /*BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, 128, 128), System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);
                        writeableBitmap.Lock();

                        System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, writeableBitmap.BackBuffer, 0, bitmapData.Stride * bitmapData.Height);

                        writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, bitmap.Width, bitmap.Height));
                        writeableBitmap.Unlock();
                        bitmap.UnlockBits(bitmapData); */



                        //VirtualDeskForm.cardFrame = clientFunc.BytesToBitmapImage(mstream);
                        //VirtualDeskForm.cardFrame = (BitmapImage)sourceConverter.ConvertFrom(scene);
                        //VirtualDeskForm.cardFrame = clientFunc.BitmapToBitmapImage(scene);
                        //Trace.WriteLine($"X:{destPoint.X}，Y:{destPoint.Y}，");
                        //Trace.Flush();

                    }
                    catch (Exception e)
                    {
                        Trace.WriteLine(DateTime.Now);
                        Trace.WriteLine($"{destPoint.X}，{destPoint.Y},");
                        //Trace.WriteLine($"{RenderingRect.X}，{RenderingRect.Y},{RenderingRect.Width}, {RenderingRect.Height}");
                        //Trace.WriteLine($"{RenderingRect.X+ RenderingRect.Width}，{RenderingRect.Y+ RenderingRect.Height},");
                        Trace.WriteLine(e);
                        Trace.Flush();
                        Trace.Close();
                        clientFunc.ShowErrorlog(e.Message);
                        break;
                        //throw;
                    }

                    //finally
                    //{
                    //    if (scene != null)
                    //    {
                    //        scene.Dispose();
                    //    }

                    //    if (sceneGraphics != null)
                    //    {
                    //        sceneGraphics.Dispose();
                    //    }

                    //    if (mstream != null)
                    //    {
                    //        mstream.Close();
                    //    }
                    //}
                }
            }


              //VirtualDesktopSyncHash.VirtualDesktop.Close();
              
              );
            //DesktopUpdater.Start();



        }

        public void IngressEventUpdater(ClientIO Client, Hashtable virtualDesktopSyncHash, ClipboardMode Clipboard)
        {
            Task IngressEventUpdater = new Task(() =>
            {
                while (true)
                {
                    try
                    {
                        var jsonEvent = Client.Reader.ReadLine();
                    }
                    catch (Exception)
                    {

                        //throw;
                        break;
                    }
                    try
                    {
                        var jsonEvent = Client.Reader.ReadLine();
                        SEvent jsonobj = (SEvent)JsonConvert.DeserializeObject(jsonEvent, typeof(SEvent));
                        switch ((InputEvent)jsonobj.Id)
                        {
                            case InputEvent.MouseCursorUpdated:
                                {
                                    if (jsonobj.Cursore != null)
                                    {
                                        Cursor newcur = Cursors.Arrow;
                                        switch ((CursorType)jsonobj.Cursore)
                                        {
                                            case CursorType.IDC_APPSTARTING:
                                                newcur = Cursors.AppStarting;
                                                break;
                                            case CursorType.IDC_ARROW:
                                                newcur = Cursors.Arrow;
                                                break;
                                            case CursorType.IDC_CROSS:
                                                newcur = Cursors.Cross;
                                                break;
                                            case CursorType.IDC_HAND:
                                                newcur = Cursors.Hand;
                                                break;
                                            case CursorType.IDC_HELP:
                                                newcur = Cursors.Help;
                                                break;
                                            case CursorType.IDC_IBEAM:
                                                newcur = Cursors.IBeam;
                                                break;
                                            //case CursorType.IDC_ICON:
                                            //    newcur = Cursors.No;
                                            //    break;
                                            case CursorType.IDC_NO:
                                                newcur = Cursors.No;
                                                break;
                                            case CursorType.IDC_SIZE:
                                                newcur = Cursors.SizeAll;
                                                break;
                                            case CursorType.IDC_SIZEALL:
                                                newcur = Cursors.SizeAll;
                                                break;
                                            case CursorType.IDC_SIZENESW:
                                                newcur = Cursors.SizeNESW;
                                                break;
                                            case CursorType.IDC_SIZENS:
                                                newcur = Cursors.SizeNS;
                                                break;
                                            case CursorType.IDC_SIZENWSE:
                                                newcur = Cursors.SizeNWSE;
                                                break;
                                            case CursorType.IDC_SIZEWE:
                                                newcur = Cursors.SizeWE;
                                                break;
                                            case CursorType.IDC_UPARROW:
                                                newcur = Cursors.UpArrow;
                                                break;
                                            case CursorType.IDC_WAIT:
                                                newcur = Cursors.WaitCursor;
                                                break;
                                            default:
                                                break;
                                        }

                                        //VirtualDeskForm.pictureBox1.Cursor = newcur;
                                    }
                                    else { continue; }


                                }
                                break;

                            case InputEvent.ClipboardUpdated:
                                {
                                    if (Clipboard == ClipboardMode.Disabled
                                        || Clipboard == ClipboardMode.Send)
                                    {
                                        continue;

                                    }

                                    HostSyncHash.Clear();
                                    HostSyncHash.Add("ClipboardText", jsonobj.Text);


                                }

                                break;
                            case InputEvent.DesktopActive:
                                break;
                            case InputEvent.DesktopInactive:
                                break;
                            default:
                                break;
                        }
                    }
                    catch (Exception)
                    {

                        throw;
                        continue;
                    }


                }
            }
            );
            IngressEventUpdater.Start();


        }

        public void EgressEventUpdater(Hashtable virtualDesktopSyncHash, ClipboardMode Clipboard)
        {
            Task EgressEventUpdater = new Task(() =>
            {

                Stopwatch stopWatch = Stopwatch.StartNew();
                while (true)
                {
                    if (stopWatch.ElapsedMilliseconds >= 1000)
                    {
                        try
                        {
                            bool eventTriggered = false;

                            if (!eventTriggered)
                            {
                                object dd = new { };
                                if (!sendEvent(OutputEvent.KeepAlive, dd))
                                {
                                    break;
                                }

                            }
                        }
                        //catch (Exception)
                        //{

                        //    throw;
                        //}
                        finally
                        {
                            stopWatch.Restart();
                        }
                    }
                }
            });
            EgressEventUpdater.Start();
        }



        public void VirtualDeskFormIO_closing(object sender, FormClosingEventArgs e)
        {
            this.session.CloseSession();
        }

        public PSCustomObject MouseEvent(int X, int Y, MouseState type, string button = "")
        {
            var CustomObject = new PSCustomObject();
            CustomObject.Id = (int)OutputEvent.MouseClickMove;
            CustomObject.X = X;
            CustomObject.Y = Y;
            CustomObject.Button = button;
            CustomObject.Type = type;
            return CustomObject;
        }

        public PSCustomObject KeyboardEvent(string Keys = "")
        {
            var CustomObject = new PSCustomObject();
            CustomObject.Id = (int)OutputEvent.Keyboard;

            CustomObject.Keys = Keys;
            return CustomObject;
        }

        public bool sendEvent(OutputEvent oee, object data)
        {
            try
            {
                if (data == null)
                {
                    data = new { Id = oee };
                }
                else
                {
                }
                data = new { Id = oee };
                //session.ClientEvents.WriteJson(data);
                outputEventSyncDic["outputEvent"].WriteJson(data);

                return true;
            }
            catch (Exception)
            {
                return false;
                //throw;
            }

        }

        public void SendVirtualMouse(int X, int Y, MouseState type, string button = "")
        {
            if (session.ViewerConfiguration.RequireResize)
            {
                X = (int)(X * session.ViewerConfiguration.ScreenX_Ratio);
                Y = (int)(Y * session.ViewerConfiguration.ScreenY_Ratio);
            }

            X += session.ViewerConfiguration.ScreenX_Delta;
            Y += session.ViewerConfiguration.ScreenY_Delta;

            //PSCustomObject temp = MouseEvent(X, Y, type, button);
            object temp = new
            {
                X = X,
                Y = Y,
                Type = type,
                Button = button,
            };
            try
            {
                //outputEventSyncHash.WriteJson(temp);
                //session.ClientEvents.WriteJson(temp);
                outputEventSyncDic["outputEvent"].WriteJson(temp);

            }
            catch (Exception)
            {

                //throw;
            }
        }

        public void SendVirtualKeyboard(string Keys = "")
        {
            object temp = new { Id = OutputEvent.Keyboard, Keys = Keys };

            try
            {
                //session.ClientEvents.WriteJson(temp);
                outputEventSyncDic["outputEvent"].WriteJson(temp);

            }
            catch (Exception)
            {

                //throw;
            }
        }

        public void logic_MouseDown(object sender, MouseEventArgs e)
        {
            SendVirtualMouse(e.X, e.Y, MouseState.Down, e.Button.ToString());
        }

        public void logic_MouseUp(object sender, MouseEventArgs e)
        {
            SendVirtualMouse(e.X, e.Y, MouseState.Up, e.Button.ToString());

        }

        public void logic_MouseMove(object sender, MouseEventArgs e)
        {
            SendVirtualMouse(e.X, e.Y, MouseState.Move, e.Button.ToString());

        }

        public void logic_MouseWheel(object sender, MouseEventArgs e)
        {
            object temp = new
            {
                Id = OutputEvent.MouseWheel,
                Delta = e.Delta
            };
            try
            {
                //session.ClientEvents.WriteJson(temp);
                outputEventSyncDic["outputEvent"].WriteJson(temp);

            }
            catch (Exception)
            {

                //throw;
            }

        }

        public void logic_DoubleClick(object sender, EventArgs e)
        {
        }

        public void logic_KeyPress(object sender, KeyPressEventArgs e)
        {
            string keychar = "";
            switch (e.KeyChar.ToString())
            {
                case "{":
                    keychar = "{{}";
                    break;
                case "}":
                    keychar = "{}}";
                    break;
                case "+":
                    keychar = "{+}";
                    break;
                case "^":
                    keychar = "{^}";
                    break;
                case "%":
                    keychar = "{%}";
                    break;
                case "~":
                    keychar = "{~}";
                    break;
                case "(":
                    keychar = "{(}";
                    break;
                case ")":
                    keychar = "{)}";
                    break;

                case "[":
                    keychar = "{[}";
                    break;
                case "]":
                    keychar = "{]}";
                    break;

                default:
                    keychar = e.KeyChar.ToString();
                    break;
            }

            SendVirtualKeyboard(keychar);


        }

        public void logic_KeyUp(object sender, KeyEventArgs e)
        {

        }

        public void logic_KeyDown(object sender, KeyEventArgs e)
        {
            string res = "";
            if (Map.funcKeymap.ContainsKey(e.KeyValue))
            {
                res = Map.funcKeymap[e.KeyValue];
            }

            if (string.IsNullOrEmpty(res))
            {
                SendVirtualKeyboard(res);
            }
        }

        public void logic_Leave(object sender, EventArgs e)
        {

        }


        //public void FormAddShown(System.Windows.Forms.Form Form1)
        //{
        //    //Center Virtual Desktop Form
        //    VirtualDeskForm.Location = new Point(
        //                   (clientFunc.GetLocalScreenWidth() - VirtualDeskForm.Width) / 2,
        //                   (clientFunc.GetLocalScreenHeight() - VirtualDeskForm.Height) / 2
        //               );

        //    VirtualDeskForm.TopMost = AlwaysOnTop;
        //}

        //public void logic_OpenNewWindow(object sender, EventArgs e)
        //{
        //    if (sender == null) { return; };
        //    ToolStripMenuItem sendered = (ToolStripMenuItem)sender;
        //    if (sendered.Text.StartsWith("OPEN"))
        //    {
        //        ViewerControl sessionControlViewer = new ViewerControl(this.Server, this.wininfo);
        //        sessionControlViewer.VirtualDeskForm.Show();

        //    }
        //    if (sendered.Text.StartsWith("XWindow"))
        //    {
        //        cmdWindow cWin = new cmdWindow();
        //        cWin.textBox1.Text = this.Server.ToString();
        //        cWin.Server = this.Server;
        //        cWin.Show();
        //    }
        //}











    }
}
